﻿using Mate.Core.Base;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using SqlSugar;

namespace Mate.Db.SqlSugar
{
    public abstract class DataService<T> where T : BaseModel, new()
    {
        public readonly DataClient dataClient;
        public DataService(DataClient dataClient)
        {
            this.dataClient = dataClient;
        }

        public ISugarQueryable<T> Queryable
        {
            get
            {
                return dataClient.Queryable<T>();
            }
        }

        public ISugarQueryable<T1, T2> QueryableJoin<T1,T2> (Expression<Func<T1, T2, object[]>> joinExpression)
        {
            return dataClient.Queryable(joinExpression);
        }

        public ISugarQueryable<T1, T2,T3> QueryableJoin<T1, T2, T3>(Expression<Func<T1, T2, T3, object[]>> joinExpression)
        {
            return dataClient.Queryable(joinExpression);
        }


        #region get model
        public T Get(Expression<Func<T, bool>> where, Expression<Func<T, object>> orderBy = null, OrderByType orderByType = OrderByType.Asc)
        {
            if (orderBy != null)
            {
                Queryable.OrderBy(orderBy, orderByType);
            }
            return Queryable.First(where);
        }
        #endregion


        public IList<T> GetList(Expression<Func<T, bool>> where, Expression<Func<T, object>> orderBy = null, OrderByType orderByType = OrderByType.Asc)
        {
            if (orderBy != null)
            {
                Queryable.OrderBy(orderBy, orderByType);
            }
            return Queryable.Where(where).ToList();
        }
        

        public IList<T> GetPageList(int pageIndex, int pageSize, Expression<Func<T, bool>> where, Expression<Func<T, object>> orderBy, ref int totalCount, OrderByType orderByType = OrderByType.Asc)
        {
            var list = Queryable.Where(where).OrderBy(orderBy, orderByType).ToPageList(pageIndex, pageSize, ref totalCount);
            return list;
        }


        public int Insert(T model)
        {
            return dataClient.Insertable(model).ExecuteCommand();
        }

        public int Update(T model)
        {
            return dataClient.Updateable(model)
                .ExecuteCommand();
        }

        public int Update(T model, Expression<Func<T, object>> updateColumns, Expression<Func<T, object>> whereColumns)
        {
            return dataClient.Updateable(model).UpdateColumns(updateColumns).WhereColumns(whereColumns)
              .ExecuteCommand();
        }

        public int UpdateIgnore(T model, Expression<Func<T, object>> ignoreColumns, Expression<Func<T, object>> whereColumns)
        {
            return dataClient.Updateable(model).IgnoreColumns(ignoreColumns).WhereColumns(whereColumns)
              .ExecuteCommand();
        }

        public int Delete(Expression<Func<T, bool>> expression)
        {
            return dataClient.Deleteable<T>(expression).ExecuteCommand();
        }

        public void Dispose()
        {
            dataClient?.Close();
            dataClient?.Dispose();
        }
    }
}
